package com.zxx.casserver.modules.role.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.zxx.cascommon.base.exception.DataNoChangeException;
import com.zxx.cascommon.base.exception.DataNotExistException;
import com.zxx.casserver.modules.role.entity.RoleDO;
import com.zxx.casserver.modules.role.entity.RolePermissionDO;
import com.zxx.casserver.modules.role.entity.RoleVO;
import com.zxx.casserver.modules.role.mapper.RoleMapper;
import com.zxx.casserver.modules.role.service.IRolePermissionService;
import com.zxx.casserver.modules.role.service.IRoleService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.List;

/**
 * 角色管理-服务实现类
 *
 * @author zhoukai
 * @since 2020-06-30
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleDO> implements IRoleService {

    private final IRolePermissionService rolePermissionService;

    public RoleServiceImpl(IRolePermissionService rolePermissionService) {
        this.rolePermissionService = rolePermissionService;
    }

    @Override
    public IPage<RoleDO> listRole(RoleVO roleVO) {
        Page<RoleDO> page = new Page<>(roleVO.getCurPage(), roleVO.getPageSize());
        QueryWrapper<RoleDO> queryWrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(roleVO.getIds())) {
            queryWrapper.in("role_id", roleVO.getIds());
        }
        if (!ObjectUtils.isEmpty(roleVO.getRoleId())) {
            queryWrapper.eq("role_id", roleVO.getRoleId());
        }
        if (!ObjectUtils.isEmpty(roleVO.getName())) {
            queryWrapper.eq("name", roleVO.getName());
        }
        if (!ObjectUtils.isEmpty(roleVO.getPlatformId())) {
            queryWrapper.eq("platform_id", roleVO.getAppId());
        }
        if (!ObjectUtils.isEmpty(roleVO.getAppId())) {
            queryWrapper.eq("app_id", roleVO.getAppId());
        }
        if (!ObjectUtils.isEmpty(roleVO.getStartTime())) {
            queryWrapper.ge("create_time", roleVO.getStartTime());
        }
        if (!ObjectUtils.isEmpty(roleVO.getEndTime())) {
            queryWrapper.le("create_time", roleVO.getEndTime());
        }
        if (!ObjectUtils.isEmpty(roleVO.getColumns()) && !ObjectUtils.isEmpty(roleVO.getAsc())) {
            String columnNames = Joiner.on(",").join(roleVO.getColumns());
            if (roleVO.getAsc()) {
                queryWrapper.orderByAsc(columnNames);
            } else {
                queryWrapper.orderByDesc(columnNames);
            }
        } else {
            queryWrapper.orderByDesc("create_time");
        }
        return page(page, queryWrapper);
    }

    @Override
    public RoleDO saveRole(RoleVO roleVO) {
        RoleDO roleDO = JSON.parseObject(JSON.toJSONString(roleVO), RoleDO.class);
        roleDO.setCreateTime(System.currentTimeMillis());
        roleDO.setUpdateTime(System.currentTimeMillis());

        boolean isSave = save(roleDO);
        if (!isSave) {
            return null;
        }
        //删除之前旧的角色权限
        rolePermissionService.removeRolePermission(roleVO.getRoleId());
        //保存用户角色权限
        if (!ObjectUtils.isEmpty(roleVO.getRolePermissionList())) {
            rolePermissionService.saveBatchRolePermission(roleVO.getRolePermissionList());
        }
        return roleDO;
    }

    @Override
    public RoleDO updateRole(RoleVO roleVO) {
        RoleDO oldRole = getById(roleVO.getRoleId());
        if (ObjectUtils.isEmpty(oldRole)) {
            throw new DataNotExistException();
        }

        RoleDO roleDO = checkChange(roleVO, oldRole);
        if (ObjectUtils.isEmpty(roleDO)) {
            throw new DataNoChangeException();
        }

        boolean isUpdate = updateById(roleDO);
        if (!isUpdate) {
            return null;
        }
        //如果更新用户角色权限
        if (!ObjectUtils.isEmpty(roleVO.getRolePermissionList())) {
            //删除之前旧的角色权限
            rolePermissionService.removeRolePermission(roleVO.getRoleId());
            //保存用户角色权限
            if (!ObjectUtils.isEmpty(roleVO.getRolePermissionList())) {
                rolePermissionService.saveBatchRolePermission(roleVO.getRolePermissionList());
            }
        }
        return roleDO;
    }

    @Override
    public RoleDO removeRole(RoleVO roleVO) {
        RoleDO oldRole = getById(roleVO.getRoleId());
        if (ObjectUtils.isEmpty(oldRole)) {
            throw new DataNotExistException();
        }
        boolean idDelete = removeById(roleVO.getRoleId());
        if (!idDelete) {
            return null;
        }
        //删除之前旧的角色权限
        return rolePermissionService.removeRolePermission(roleVO.getRoleId()) ? oldRole : null;
    }

    @Override
    public RoleVO getRole(RoleVO roleVO) {
        //根据角色ID获取角色信息
        RoleDO roleDO = getById(roleVO.getRoleId());
        if (ObjectUtils.isEmpty(roleDO)) {
            throw new DataNotExistException();
        }
        RoleVO roleBO = JSON.parseObject(JSON.toJSONString(roleVO), RoleVO.class);

        //获取角色关联的权限
        QueryWrapper<RolePermissionDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleVO.getRoleId());
        List<RolePermissionDO> rolePermissionList = rolePermissionService.list();
        roleBO.setRolePermissionList(rolePermissionList);
        return roleBO;
    }

    /**
     * 根据传入的角色信息与数据库的角色进行比较
     *
     * @return 返回待修改属性不一样的值
     * @author zhoukai
     * @date 2020/7/30 18:24
     */
    private RoleDO checkChange(RoleVO roleVO, RoleDO oldRole) {
        RoleDO roleDO = new RoleDO();
        roleDO.setRoleId(roleVO.getRoleId());
        roleDO.setUpdateTime(System.currentTimeMillis());
        boolean isChange = false;
        if (!ObjectUtils.isEmpty(roleVO.getName()) && !roleVO.getName().equals(oldRole.getName())) {
            oldRole.setName(oldRole.getName());
            isChange = true;
        }
        if (!ObjectUtils.isEmpty(roleVO.getRemark()) && !roleVO.getRemark().equals(oldRole.getRemark())) {
            oldRole.setRemark(oldRole.getRemark());
            isChange = true;
        }

        if (!ObjectUtils.isEmpty(roleVO.getRolePermissionList())) {
            isChange = true;
        }

        return isChange ? roleDO : null;
    }
}
